package com.yuanlang.web.socket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yuanlang.facade.model.im.ImUser;
import com.yuanlang.facade.model.im.util.ImSocketMsg;
import com.yuanlang.facade.model.socket.MessageResultVo;
import com.yuanlang.facade.model.system.TsUser;
import com.yuanlang.services.im.ImMessageHandlerService;
import com.yuanlang.services.im.ImUserService;
import com.yuanlang.services.redis.RedisClientTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * company 重庆源狼软件科技有限责任公司
 * FileName WebSocketMessageHandler
 * Package com.yuanlang.web.socket
 * Description 消息通知
 * author huangxueqian
 * create 2018-05-18 9:52
 * version V1.0
 */
public class WebSocketMessageHandler extends  TextWebSocketHandler {
    public static Map<Long, WebSocketSession> users ; // 存储登录用户的数据
    private static Logger logger = LoggerFactory.getLogger(WebSocketMessageHandler.class);
    static {
        users = new HashMap<>(); // 用来存放 存储登录用户的数据
    }
    @Autowired(required = false)
    private RedisClientTemplate redisClientTemplate;
    @Autowired
    ImMessageHandlerService handlerService ;
    @Autowired
    ImUserService userService ;
   /**
     * 接收到客户端消息时调用
     * @param session
     * @param message
     * synchronized void
     */
    @Override
    public  synchronized void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String messageStr = message.getPayload() ;
        ImSocketMsg msg = JSON.parseObject(messageStr,ImSocketMsg.class);
        /**
         * type = onOpen 连接
         * type = sendMessage 发送消息
         * type = onClose 关闭
         * type = onMessage 接受信息
         * type = sys // 系统消息
         */
        String access_token = (String) session.getAttributes().get("access_token");
        logger.info("session--->"+access_token+"-------------->");
        logger.info("消息字符串--->"+messageStr);
        switch (msg.getType()){
                case "onOpen":
                    logger.info("handleTextMessage---->onOpen:连接--->");
                 // 当连接的时候，则提示其他在线用户上线了。
                 // 通知用户
                    break;
                case "sendMessage":
                    // 发送消息 ;
                    handlerService.messageHandler(message,users);
                    //发送对应的消息
                    break;
                case "onClose":
                    //从用户内存中移除掉用户
                    //发送对应的消息
                    break;
                case "onMessage":
                    // 从用户接受消息后，将消息状态设置为已读
                    // 并更新数据库
                    break;

        }
        logger.info("WebSocketMessageHandler：进入handleTextMessage----------------");
       // super.handleTextMessage(session, message);
       // TextMessage returnMessage = new TextMessage(message.getPayload() + " received at server");
       logger.info("WebSocketMessageHandler：handleTextMessage-----------------结束");
    }

    /**
     * 与客户端完成连接后调用
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session)
            throws Exception {
        logger.info("afterConnectionEstablished-----------------");
        // 从session会话中获取token数据 ，使用sessionId 作为access_token
        //用token去redis中查出用户信息
        String access_token = (String) session.getAttributes().get("access_token");
        String tsUserStr = redisClientTemplate.get(access_token);
        //判断token是否被人篡改(如果被篡改，查不出employee)、或者不存在
        if (tsUserStr == null) {
            logger.info("afterConnectionEstablished-------------->>Redis中不存在该token");
            return;
        }
        TsUser tsUser = JSON.parseObject(tsUserStr, TsUser.class);
        logger.info("用户信息：{}", JSON.toJSON(tsUserStr));
        // map中保存的key为用户的id, value 为 websocket session会话
        users.put(tsUser.getUserId(), session);
        ImUser user = new ImUser();
        user.setId(tsUser.getUserId());
        user.setStatus("online");
        userService.updateImUser(user);
        logger.info("======================================》当前有:" + users.size() + "个用户在线");
        logger.info("afterConnectionEstablished-----------------结束");
    }

    /**
     * 消息传输出错时调用
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session,
                                     Throwable exception) throws Exception {
        logger.info("进入handleTransportError---------------------");
        logger.info("======================================》当前有:" + users.size() + "个用户在线");
        // 获取token数据
        String access_token = (String) session.getAttributes().get("access_token");
        String tsUserStr = redisClientTemplate.get(access_token);
        TsUser tsUser = JSON.parseObject(tsUserStr, TsUser.class);
        //判断token是否被人篡改(如果被篡改，查不出employee)、或者不存在
        logger.info("用户信息：{}", JSON.toJSON(tsUserStr));
        if (tsUserStr == null) {
            logger.info("handleTransportError--------------->>Redis中不存在该token");
            return;
        }
        //如果users没有登录的用户
        if (users != null && users.size() != 0) {
            // 将会话移除
            users.remove(tsUser.getUserId());
        }
        logger.info("handleTransportError----------------------结束");
    }

    /**
     * 一个客户端连接断开时关闭
     * @param session
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session,
                                      CloseStatus closeStatus) throws Exception {
        logger.info("afterConnectionClosed---------------------------");
        // 获取token数据
        String access_token = session.getId();
        String tsUserStr = redisClientTemplate.get(access_token);
        TsUser tsUser = JSON.parseObject(tsUserStr, TsUser.class);
        logger.info("用户信息：{}", tsUserStr);
        if (tsUser == null) {
            logger.info("afterConnectionEstablished---------------Redis中不存在该token");
            return;
        }
        //如果users没有登录的用户
        if (users != null && users.size() != 0) {
            //将会话移除
            users.remove(tsUser.getUserId());
        }

        ImUser user = new ImUser();
        user.setId(tsUser.getUserId());
        user.setStatus("");
        userService.updateImUser(user); // 更新当前用户状态
        logger.info("afterConnectionClosed : session " + JSON.toJSONString(session));
        logger.info("用户：{},离开系统", tsUser.getUserName());
        //当用户关闭浏览器后，需要将会话从list中移除
        logger.info("======================================》当前有:" + users.size() + "个用户在线");
        logger.info("afterConnectionClosed---------------------------结束");
    }
    @Override
    public boolean supportsPartialMessages() {
        // TODO Auto-generated method stub
        logger.info("进入supportsPartialMessages");
        return false;
    }

}
